/*
 * Stack_Link.c
 *
 *  Created on: Dec 14, 2011
 *      Author: sanglei
 * Description: 这是一个通用栈，用链表实现的。
 */
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "../headers/stack_link.h"

int initStack(Stack * const pstk,const unsigned data_byte){

	assert(pstk!=NULL);//若条件为假，则报"断言"错误
	assert(data_byte>0);

	pstk->head = NULL;
	pstk->byte = data_byte;

	return 1;
}

int push_stack_link(Stack *pstk,const void * pvalue){ //头插法

	assert(pstk!=NULL);
	assert(pvalue!=NULL);

	Node *ptmp = pstk->head;
	if((pstk->head = malloc(sizeof(Node))) == 0){//生成一个空节点
		return 0;
	}

	//生成k个字节的空间，用void *指向。其中k = stack->byte
	if((pstk->head->pvalue = malloc(pstk->byte)) == 0){
		return 0;
	}

	//例如：void *p,*q; memcpy(p,q,size);
	//将q内存中的值复制到p对应的内存中，复制的长度为size
	memcpy(pstk->head->pvalue,pvalue,pstk->byte);

	pstk->head->next = ptmp;
	return 1;

}

int dropStack(Stack* pstk){
	void * tmp = malloc(pstk->byte);//先申请一块空闲内存，用于存放弹出来的值
	while(!isEmpty_stack_link(pstk)){
		pop_stack_link(pstk,tmp);
	}
	free(tmp);
	return 1;
}

int pop_stack_link(Stack *pstk,void *pret){

	assert(pstk!=NULL);
	assert(pstk!=NULL);
	if(!isEmpty_stack_link(pstk)){
		memcpy(pret,pstk->head->pvalue,pstk->byte);//赋值
		Node *tofree = pstk->head;
		pstk->head = pstk->head->next;
		free(tofree->pvalue);//释放掉节点内部请求的空间！
		free(tofree);
		return 1;
	}else{
		return 0;
	}
}

int isEmpty_stack_link(Stack* pstk){
	assert(pstk!=NULL);
	if(pstk->head == NULL){
		return 1;
	}else{
		return 0;
	}
}

void main_stack_link(){//通用栈的用法
	Stack sp;
	initStack(&sp,sizeof(int));
	int y = 12;
	push_stack_link(&sp,&y);
	int x;
	pop_stack_link(&sp,&x);
	printf("%d\n",x);
}
